/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * RegBackupMainForm.java
 *
 * Created on 25.04.2010, 20:54:23
 */

package shaman;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.Annotations;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.awt.event.ActionEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.jdesktop.application.Action;
import org.jdesktop.application.Application;
import shaman.storage.BackupTask;
import shaman.storage.Rule;
import shaman.dialog.util.ExtensionFileFilter;
import shaman.storage.Factory;
import shaman.storage.FilterList;
import shaman.storage.StorageList;
import shaman.storage.api.Filter;
import shaman.storage.api.Storage;
import shaman.storage.impl.filter.published.CryptFilter;
import shaman.storage.impl.filter.published.DeflateFilter;
import shaman.storage.impl.local.LocalStorage;

/**
 *
 * @author Shaman
 */

class MenuItemFilterAction extends AbstractAction
{

    RegBackupMainForm rbmf = null;

    public MenuItemFilterAction (RegBackupMainForm rbmf)
    {
        this.rbmf = rbmf;
    }

    public void actionPerformed(ActionEvent e) {
        if (rbmf == null)
            throw new UnsupportedOperationException("Поле формы не инициализировано.");
        System.out.println("Filter creating:");
        JMenuItem sender = (JMenuItem) e.getSource();
        System.out.println("sender: "+sender.toString());
        System.out.println("sendet.getText() = "+sender.getText());
        Filter filter = FilterList.getFactoryMap().get(sender.getText()).newObject();
        if (rbmf.getSelectedTask().getFilters().add(filter))
            rbmf.getSelectedTask().setChanged(true);
        rbmf.getFilterTable().updateUI();
    }

}

class MenuItemStorageAction extends AbstractAction
{

    RegBackupMainForm rbmf = null;

    public MenuItemStorageAction (RegBackupMainForm rbmf)
    {
        this.rbmf = rbmf;
    }

    public void actionPerformed(ActionEvent e) {
        if (rbmf == null)
            JOptionPane.showMessageDialog(rbmf, "Поле формы не инициализировано!", "Ошибка", JOptionPane.WARNING_MESSAGE);
        System.out.println("Storage creating:");
        JMenuItem sender = (JMenuItem) e.getSource();
        System.out.println("sender: "+sender.toString());
        System.out.println("sendet.getText() = "+sender.getText());
        Storage storage = StorageList.getFactoryMap().get(sender.getText()).newObject();
        if (rbmf.getSelectedTask().getStorages().add(storage))
            rbmf.getSelectedTask().setChanged(true);
        rbmf.getStorageTable().updateUI();
    }

}

public class RegBackupMainForm extends javax.swing.JFrame {

    /** Creates new form RegBackupMainForm */
    public RegBackupMainForm() {
        initComponents();
    }

    public RegBackupMainForm(Application app) {
        initComponents();

        loadTaskList();

        //FIXME: This code is temprorary and must be deleted in future
        System.out.println("Filter List add: " + CryptFilter.class.toString());
        new CryptFilter();
        System.out.println("Filter List add: " + DeflateFilter.class.toString());
        new DeflateFilter();
        System.out.println("Storage List add: " + LocalStorage.class.toString());
        new LocalStorage();
        //-------------------------------

        this.app = app;

        //Init jFilterMenu
        for (String filterName : FilterList.getFactoryMap().keySet())
        {
            System.out.println("Filter factory add: "+filterName);
            JMenuItem menuItem = new JMenuItem();
            menuItem.setAction(new MenuItemFilterAction(this));
            menuItem.setText(filterName);
            menuItem.setName(filterName);
            jFilterMenu.add(menuItem);
        }

        //Init jStorageMenu
        for (String storageName : StorageList.getFactoryMap().keySet())
        {
            System.out.println("Storage factory add: "+storageName);
            JMenuItem menuItem = new JMenuItem();
            menuItem.setAction(new MenuItemStorageAction(this));
            menuItem.setText(storageName);
            menuItem.setName(storageName);
            jStorageMenu.add(menuItem);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jFilterMenu = new javax.swing.JPopupMenu();
        jStorageMenu = new javax.swing.JPopupMenu();
        jPopupFilter = new javax.swing.JPopupMenu();
        miEditFilter = new javax.swing.JMenuItem();
        miDelFilter = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        miFilterUp = new javax.swing.JMenuItem();
        miFilterDown = new javax.swing.JMenuItem();
        jTaskMenu = new javax.swing.JPopupMenu();
        miTaskAdd = new javax.swing.JMenuItem();
        miTaskDel = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        miTaskUp = new javax.swing.JMenuItem();
        miTaskDown = new javax.swing.JMenuItem();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTaskList = new javax.swing.JList();
        jbAddTask = new javax.swing.JButton();
        jTabPanes = new javax.swing.JTabbedPane();
        jPanelMain = new javax.swing.JPanel();
        jStatusLabel = new javax.swing.JLabel();
        jStatus = new javax.swing.JLabel();
        jLastRunLabel = new javax.swing.JLabel();
        jLastRun = new javax.swing.JLabel();
        jbBackupRun = new javax.swing.JButton();
        jbRestoreRun = new javax.swing.JButton();
        jProgressBar = new javax.swing.JProgressBar();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTextLog = new javax.swing.JTextArea();
        jPanelConfig = new javax.swing.JPanel();
        jRuleTableLabel = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jRuleTable = new javax.swing.JTable();
        jStorageTableLabel = new javax.swing.JLabel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jStorageTable = new javax.swing.JTable();
        jFilterTableLabel = new javax.swing.JLabel();
        jScrollPane5 = new javax.swing.JScrollPane();
        jFilterTable = new javax.swing.JTable();
        jTaskNameLabel = new javax.swing.JLabel();
        jTaskName = new javax.swing.JTextField();
        jbDelRule = new javax.swing.JButton();
        jbEditRule = new javax.swing.JButton();
        jbAddRule = new javax.swing.JButton();
        jbAddFilter = new javax.swing.JButton();
        jbEditFilter = new javax.swing.JButton();
        jbDelFilter = new javax.swing.JButton();
        jbDelStorage = new javax.swing.JButton();
        jbEditStorage = new javax.swing.JButton();
        jbAddStorage = new javax.swing.JButton();
        jSeparator3 = new javax.swing.JSeparator();
        jSeparator4 = new javax.swing.JSeparator();
        jShowFileList = new javax.swing.JButton();
        jbSaveTask = new javax.swing.JButton();
        jbUndoTaskChanges = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu mmFile = new javax.swing.JMenu();
        miLoadTask = new javax.swing.JMenuItem();
        miSaveTask = new javax.swing.JMenuItem();
        jExitSeparator = new javax.swing.JPopupMenu.Separator();
        javax.swing.JMenuItem miExit = new javax.swing.JMenuItem();
        javax.swing.JMenu mmHelp = new javax.swing.JMenu();
        miHelp = new javax.swing.JMenuItem();
        javax.swing.JMenuItem miAbout = new javax.swing.JMenuItem();

        jFilterMenu.setName("jFilterMenu"); // NOI18N

        jStorageMenu.setName("jStorageMenu"); // NOI18N
        jStorageMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                jStorageMenuPopupMenuWillBecomeVisible(evt);
            }
        });

        jPopupFilter.setName("jPopupFilter"); // NOI18N
        jPopupFilter.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                jPopupFilterPopupMenuWillBecomeVisible(evt);
            }
        });

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(shaman.RegBackupApp.class).getContext().getActionMap(RegBackupMainForm.class, this);
        miEditFilter.setAction(actionMap.get("editFilter")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(shaman.RegBackupApp.class).getContext().getResourceMap(RegBackupMainForm.class);
        miEditFilter.setText(resourceMap.getString("miEditFilter.text")); // NOI18N
        miEditFilter.setToolTipText(resourceMap.getString("miEditFilter.toolTipText")); // NOI18N
        miEditFilter.setName("miEditFilter"); // NOI18N
        jPopupFilter.add(miEditFilter);

        miDelFilter.setAction(actionMap.get("delFilter")); // NOI18N
        miDelFilter.setText(resourceMap.getString("miDelFilter.text")); // NOI18N
        miDelFilter.setToolTipText(resourceMap.getString("miDelFilter.toolTipText")); // NOI18N
        miDelFilter.setName("miDelFilter"); // NOI18N
        jPopupFilter.add(miDelFilter);

        jSeparator1.setName("jSeparator1"); // NOI18N
        jPopupFilter.add(jSeparator1);

        miFilterUp.setAction(actionMap.get("moveUpFilter")); // NOI18N
        miFilterUp.setText(resourceMap.getString("miFilterUp.text")); // NOI18N
        miFilterUp.setToolTipText(resourceMap.getString("miFilterUp.toolTipText")); // NOI18N
        miFilterUp.setName("miFilterUp"); // NOI18N
        jPopupFilter.add(miFilterUp);

        miFilterDown.setAction(actionMap.get("moveDownFilter")); // NOI18N
        miFilterDown.setText(resourceMap.getString("miFilterDown.text")); // NOI18N
        miFilterDown.setToolTipText(resourceMap.getString("miFilterDown.toolTipText")); // NOI18N
        miFilterDown.setName("miFilterDown"); // NOI18N
        jPopupFilter.add(miFilterDown);

        jTaskMenu.setName("jTaskMenu"); // NOI18N
        jTaskMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                jTaskMenuPopupMenuWillBecomeVisible(evt);
            }
        });

        miTaskAdd.setText(resourceMap.getString("miTaskAdd.text")); // NOI18N
        miTaskAdd.setName("miTaskAdd"); // NOI18N
        miTaskAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addTask(evt);
            }
        });
        jTaskMenu.add(miTaskAdd);

        miTaskDel.setText(resourceMap.getString("miTaskDel.text")); // NOI18N
        miTaskDel.setName("miTaskDel"); // NOI18N
        miTaskDel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                delTask(evt);
            }
        });
        jTaskMenu.add(miTaskDel);

        jSeparator2.setName("jSeparator2"); // NOI18N
        jTaskMenu.add(jSeparator2);

        miTaskUp.setText(resourceMap.getString("miTaskUp.text")); // NOI18N
        miTaskUp.setName("miTaskUp"); // NOI18N
        jTaskMenu.add(miTaskUp);

        miTaskDown.setText(resourceMap.getString("miTaskDown.text")); // NOI18N
        miTaskDown.setName("miTaskDown"); // NOI18N
        jTaskMenu.add(miTaskDown);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setLocationByPlatform(true);
        setName("Form"); // NOI18N
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        jTaskList.setModel(Tasks);
        jTaskList.setToolTipText(resourceMap.getString("jTaskList.toolTipText")); // NOI18N
        jTaskList.setComponentPopupMenu(jTaskMenu);
        jTaskList.setName("jTaskList"); // NOI18N
        jTaskList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jTaskListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(jTaskList);

        jbAddTask.setAction(actionMap.get("CreateTask")); // NOI18N
        jbAddTask.setText(resourceMap.getString("jbAddTask.text")); // NOI18N
        jbAddTask.setName("jbAddTask"); // NOI18N
        jbAddTask.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addTask(evt);
            }
        });

        jTabPanes.setEnabled(false);
        jTabPanes.setName("jTabPanes"); // NOI18N

        jPanelMain.setName("jPanelMain"); // NOI18N

        jStatusLabel.setText(resourceMap.getString("jStatusLabel.text")); // NOI18N
        jStatusLabel.setName("jStatusLabel"); // NOI18N

        jStatus.setText(resourceMap.getString("jStatus.text")); // NOI18N
        jStatus.setName("jStatus"); // NOI18N

        jLastRunLabel.setText(resourceMap.getString("jLastRunLabel.text")); // NOI18N
        jLastRunLabel.setName("jLastRunLabel"); // NOI18N

        jLastRun.setText(resourceMap.getString("jLastRun.text")); // NOI18N
        jLastRun.setName("jLastRun"); // NOI18N

        jbBackupRun.setText(resourceMap.getString("jbBackupRun.text")); // NOI18N
        jbBackupRun.setEnabled(false);
        jbBackupRun.setName("jbBackupRun"); // NOI18N
        jbBackupRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbBackupRunActionPerformed(evt);
            }
        });

        jbRestoreRun.setText(resourceMap.getString("jbRestoreRun.text")); // NOI18N
        jbRestoreRun.setEnabled(false);
        jbRestoreRun.setName("jbRestoreRun"); // NOI18N
        jbRestoreRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbRestoreRunActionPerformed(evt);
            }
        });

        jProgressBar.setName("jProgressBar"); // NOI18N

        jScrollPane3.setName("jScrollPane3"); // NOI18N

        jTextLog.setColumns(20);
        jTextLog.setRows(5);
        jTextLog.setName("jTextLog"); // NOI18N
        jScrollPane3.setViewportView(jTextLog);

        javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
        jPanelMain.setLayout(jPanelMainLayout);
        jPanelMainLayout.setHorizontalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMainLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelMainLayout.createSequentialGroup()
                        .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanelMainLayout.createSequentialGroup()
                                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLastRunLabel)
                                    .addComponent(jStatusLabel))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jStatus)
                                    .addComponent(jLastRun)))
                            .addGroup(jPanelMainLayout.createSequentialGroup()
                                .addComponent(jbBackupRun)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jbRestoreRun, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)))
                        .addGap(425, 425, 425))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelMainLayout.createSequentialGroup()
                        .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 736, Short.MAX_VALUE)
                            .addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 736, Short.MAX_VALUE))
                        .addContainerGap())))
        );
        jPanelMainLayout.setVerticalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelMainLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jStatusLabel)
                    .addComponent(jStatus))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLastRunLabel)
                    .addComponent(jLastRun))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbBackupRun)
                    .addComponent(jbRestoreRun))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 401, Short.MAX_VALUE)
                .addContainerGap())
        );

        jTabPanes.addTab(resourceMap.getString("jPanelMain.TabConstraints.tabTitle"), jPanelMain); // NOI18N

        jPanelConfig.setName("jPanelConfig"); // NOI18N
        jPanelConfig.addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentHidden(java.awt.event.ComponentEvent evt) {
                jPanelConfigHidden(evt);
            }
        });

        jRuleTableLabel.setText(resourceMap.getString("jRuleTableLabel.text")); // NOI18N
        jRuleTableLabel.setName("jRuleTableLabel"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N

        jRuleTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        jRuleTable.setName("jRuleTable"); // NOI18N
        jRuleTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jRuleTableClick(evt);
            }
        });
        jRuleTable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jRuleTableKeyPressed(evt);
            }
        });
        jScrollPane2.setViewportView(jRuleTable);

        jStorageTableLabel.setText(resourceMap.getString("jStorageTableLabel.text")); // NOI18N
        jStorageTableLabel.setName("jStorageTableLabel"); // NOI18N

        jScrollPane4.setName("jScrollPane4"); // NOI18N

        jStorageTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {},
                {},
                {},
                {}
            },
            new String [] {

            }
        ));
        jStorageTable.setName("jStorageTable"); // NOI18N
        jScrollPane4.setViewportView(jStorageTable);

        jFilterTableLabel.setText(resourceMap.getString("jFilterTableLabel.text")); // NOI18N
        jFilterTableLabel.setName("jFilterTableLabel"); // NOI18N

        jScrollPane5.setName("jScrollPane5"); // NOI18N

        jFilterTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        jFilterTable.setColumnSelectionAllowed(true);
        jFilterTable.setComponentPopupMenu(jPopupFilter);
        jFilterTable.setName("jFilterTable"); // NOI18N
        jScrollPane5.setViewportView(jFilterTable);

        jTaskNameLabel.setText(resourceMap.getString("jTaskNameLabel.text")); // NOI18N
        jTaskNameLabel.setName("jTaskNameLabel"); // NOI18N

        jTaskName.setText(resourceMap.getString("jTaskName.text")); // NOI18N
        jTaskName.setAction(actionMap.get("renameRule")); // NOI18N
        jTaskName.setName("jTaskName"); // NOI18N

        jbDelRule.setAction(actionMap.get("delRule")); // NOI18N
        jbDelRule.setText(resourceMap.getString("jbDelRule.text")); // NOI18N
        jbDelRule.setName("jbDelRule"); // NOI18N

        jbEditRule.setAction(actionMap.get("editRule")); // NOI18N
        jbEditRule.setText(resourceMap.getString("jbEditRule.text")); // NOI18N
        jbEditRule.setName("jbEditRule"); // NOI18N
        jbEditRule.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jbEditRuleClicked(evt);
            }
        });

        jbAddRule.setAction(actionMap.get("addRule")); // NOI18N
        jbAddRule.setText(resourceMap.getString("jbAddRule.text")); // NOI18N
        jbAddRule.setName("jbAddRule"); // NOI18N

        jbAddFilter.setText(resourceMap.getString("jbAddFilter.text")); // NOI18N
        jbAddFilter.setComponentPopupMenu(jFilterMenu);
        jbAddFilter.setName("jbAddFilter"); // NOI18N
        jbAddFilter.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jbAddFilterClicked(evt);
            }
        });

        jbEditFilter.setAction(actionMap.get("editFilter")); // NOI18N
        jbEditFilter.setText(resourceMap.getString("jbEditFilter.text")); // NOI18N
        jbEditFilter.setName("jbEditFilter"); // NOI18N

        jbDelFilter.setAction(actionMap.get("delFilter")); // NOI18N
        jbDelFilter.setText(resourceMap.getString("jbDelFilter.text")); // NOI18N
        jbDelFilter.setName("jbDelFilter"); // NOI18N

        jbDelStorage.setText(resourceMap.getString("jbDelStorage.text")); // NOI18N
        jbDelStorage.setName("jbDelStorage"); // NOI18N
        jbDelStorage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbDelStorageActionPerformed(evt);
            }
        });

        jbEditStorage.setText(resourceMap.getString("jbEditStorage.text")); // NOI18N
        jbEditStorage.setName("jbEditStorage"); // NOI18N

        jbAddStorage.setText(resourceMap.getString("jbAddStorage.text")); // NOI18N
        jbAddStorage.setName("jbAddStorage"); // NOI18N
        jbAddStorage.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbAddStorageClicked(evt);
            }
        });

        jSeparator3.setName("jSeparator3"); // NOI18N

        jSeparator4.setName("jSeparator4"); // NOI18N

        jShowFileList.setText(resourceMap.getString("jShowFileList.text")); // NOI18N
        jShowFileList.setName("jShowFileList"); // NOI18N
        jShowFileList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jShowFileListActionPerformed(evt);
            }
        });

        jbSaveTask.setText(resourceMap.getString("jbSaveTask.text")); // NOI18N
        jbSaveTask.setName("jbSaveTask"); // NOI18N
        jbSaveTask.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbSaveTaskClicked(evt);
            }
        });

        jbUndoTaskChanges.setText(resourceMap.getString("jbUndoTaskChanges.text")); // NOI18N
        jbUndoTaskChanges.setName("jbUndoTaskChanges"); // NOI18N
        jbUndoTaskChanges.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbUndoTaskChangesClicked(evt);
            }
        });

        javax.swing.GroupLayout jPanelConfigLayout = new javax.swing.GroupLayout(jPanelConfig);
        jPanelConfig.setLayout(jPanelConfigLayout);
        jPanelConfigLayout.setHorizontalGroup(
            jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelConfigLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelConfigLayout.createSequentialGroup()
                        .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jRuleTableLabel, javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanelConfigLayout.createSequentialGroup()
                                .addComponent(jTaskNameLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jTaskName, javax.swing.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)))
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelConfigLayout.createSequentialGroup()
                        .addComponent(jShowFileList)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 286, Short.MAX_VALUE)
                        .addComponent(jbAddRule)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbEditRule)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbDelRule)
                        .addContainerGap())
                    .addComponent(jSeparator3, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addGroup(jPanelConfigLayout.createSequentialGroup()
                        .addComponent(jFilterTableLabel)
                        .addContainerGap(653, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelConfigLayout.createSequentialGroup()
                        .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(jPanelConfigLayout.createSequentialGroup()
                                .addComponent(jStorageTableLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 442, Short.MAX_VALUE))
                            .addGroup(jPanelConfigLayout.createSequentialGroup()
                                .addComponent(jbAddFilter)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                        .addComponent(jbEditFilter)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbDelFilter)
                        .addContainerGap())
                    .addGroup(jPanelConfigLayout.createSequentialGroup()
                        .addComponent(jbSaveTask)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbUndoTaskChanges))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelConfigLayout.createSequentialGroup()
                        .addComponent(jbAddStorage)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbEditStorage, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbDelStorage)
                        .addContainerGap())
                    .addComponent(jSeparator4, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 746, Short.MAX_VALUE)))
        );
        jPanelConfigLayout.setVerticalGroup(
            jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelConfigLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTaskNameLabel)
                    .addComponent(jTaskName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3)
                .addComponent(jRuleTableLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbAddRule)
                    .addComponent(jbEditRule)
                    .addComponent(jbDelRule)
                    .addComponent(jShowFileList))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator3, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(1, 1, 1)
                .addComponent(jFilterTableLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbEditFilter)
                    .addComponent(jbDelFilter)
                    .addComponent(jbAddFilter))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator4, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jStorageTableLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbEditStorage)
                    .addComponent(jbDelStorage)
                    .addComponent(jbAddStorage))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelConfigLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbSaveTask)
                    .addComponent(jbUndoTaskChanges))
                .addContainerGap(14, Short.MAX_VALUE))
        );

        jTaskName.getDocument().addDocumentListener(new DocumentListener() {
            public void insertUpdate(DocumentEvent e){
                //System.out.println("jTaskName insertUpdate event run");
                BackupTask selTask = getSelectedTask();
                if (selTask != null)
                {
                    //System.out.println("jTaskName task name changed");
                    selTask.setName(jTaskName.getText());
                    jTaskList.updateUI();
                }
            }
            public void removeUpdate(DocumentEvent e){
                //System.out.println("jTaskName removeUpdate event run");
                BackupTask selTask = getSelectedTask();
                if (selTask != null)
                {
                    //System.out.println("jTaskName task name changed");
                    selTask.setName(jTaskName.getText());
                    jTaskList.updateUI();
                }
            }
            public void changedUpdate(DocumentEvent e){}
        });

        jTabPanes.addTab(resourceMap.getString("jPanelConfig.TabConstraints.tabTitle"), jPanelConfig); // NOI18N

        menuBar.setName("menuBar"); // NOI18N

        mmFile.setText(resourceMap.getString("mmFile.text")); // NOI18N
        mmFile.setName("mmFile"); // NOI18N

        miLoadTask.setAction(actionMap.get("loadTask")); // NOI18N
        miLoadTask.setText(resourceMap.getString("miLoadTask.text")); // NOI18N
        miLoadTask.setName("miLoadTask"); // NOI18N
        miLoadTask.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                miLoadTaskMouseClicked(evt);
            }
        });
        mmFile.add(miLoadTask);

        miSaveTask.setAction(actionMap.get("saveTask")); // NOI18N
        miSaveTask.setText(resourceMap.getString("miSaveTask.text")); // NOI18N
        miSaveTask.setName("miSaveTask"); // NOI18N
        mmFile.add(miSaveTask);

        jExitSeparator.setName("jExitSeparator"); // NOI18N
        mmFile.add(jExitSeparator);

        miExit.setAction(actionMap.get("quit")); // NOI18N
        miExit.setText(resourceMap.getString("miExit.text")); // NOI18N
        miExit.setName("miExit"); // NOI18N
        mmFile.add(miExit);

        menuBar.add(mmFile);

        mmHelp.setText(resourceMap.getString("mmHelp.text")); // NOI18N
        mmHelp.setName("mmHelp"); // NOI18N

        miHelp.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        miHelp.setText(resourceMap.getString("miHelp.text")); // NOI18N
        miHelp.setName("miHelp"); // NOI18N
        mmHelp.add(miHelp);

        miAbout.setText(resourceMap.getString("miAbout.text")); // NOI18N
        miAbout.setName("miAbout"); // NOI18N
        miAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miAboutActionPerformed(evt);
            }
        });
        mmHelp.add(miAbout);

        menuBar.add(mmHelp);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jbAddTask, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 137, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTabPanes, javax.swing.GroupLayout.DEFAULT_SIZE, 761, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTabPanes, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 544, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 515, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbAddTask)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    public BackupTask getSelectedTask()
    {
        if (jTaskList.getSelectedIndex() != -1)
            return Tasks.get(jTaskList.getSelectedIndex());
        else
            return null;
    }

    public JTable getFilterTable()
    {
        return jFilterTable;
    }

    public JTable getStorageTable()
    {
        return jStorageTable;
    }

    private void jTaskListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jTaskListValueChanged
        BackupTask selectedTask = getSelectedTask();
        if (selectedTask != null)
        {
            if (selectedTask.isChanged())
                if (JOptionPane.showConfirmDialog(this, "Созранить изменения настроек задачи", "Вопрос", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                {
                    saveTaskList();
                    selectedTask.setChanged(false);
                }
            jTabPanes.setEnabled(true);
            jbBackupRun.setEnabled(true);
            jbRestoreRun.setEnabled(true);
            jTaskName.setText(selectedTask.getName());
            jRuleTable.setModel(selectedTask.getTableModelRules());
            jRuleTable.getColumnModel().getColumn(0).setPreferredWidth(50);
            jRuleTable.getColumnModel().getColumn(1).setPreferredWidth(100);
            jRuleTable.getColumnModel().getColumn(2).setPreferredWidth(500);
            jRuleTable.getColumnModel().getColumn(3).setPreferredWidth(200);
            jFilterTable.setModel(selectedTask.getTableModelFilters());
            jStorageTable.setModel(selectedTask.getTableModelStorages());
            saveTaskList();
        }
        else
        {
            jTabPanes.setEnabled(false);
            jTabPanes.setSelectedIndex(0);
        }
    }//GEN-LAST:event_jTaskListValueChanged

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        if (app != null)
            app.exit();
    }//GEN-LAST:event_formWindowClosed

    private void jbEditRuleClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jbEditRuleClicked
        if (getSelectedTask() != null)
            if (jRuleTable.getSelectedRow() != -1)
            {
                getSelectedTask().getRules().get(jRuleTable.getSelectedRow()).showConfigForm(this);
                jTaskList.updateUI();
            }
            else
                JOptionPane.showMessageDialog(this, "Не выбрано ни одного правила.", "Ошибка", JOptionPane.WARNING_MESSAGE);
    }//GEN-LAST:event_jbEditRuleClicked

    private void jbAddFilterClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jbAddFilterClicked
        jFilterMenu.show(jbAddFilter, 0, jbAddFilter.getHeight());
    }//GEN-LAST:event_jbAddFilterClicked

    private void jRuleTableClick(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jRuleTableClick
        if (evt.getClickCount() > 1)
        {
            getSelectedTask().getRules().get(jRuleTable.getSelectedRow()).showConfigForm(this);
            getSelectedTask().setChanged(true);
        }
        if (getSelectedTask() != null)
        {
            jbEditRule.setEnabled(true);
            jbDelRule.setEnabled(true);
        }
    }//GEN-LAST:event_jRuleTableClick

    private void miLoadTaskMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_miLoadTaskMouseClicked

    }//GEN-LAST:event_miLoadTaskMouseClicked

    private void jbBackupRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbBackupRunActionPerformed
        try {
            getSelectedTask().run(this, jProgressBar, jTextLog);
        } catch (Exception ex) {
            Logger.getLogger(RegBackupMainForm.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "Error", JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_jbBackupRunActionPerformed

    private void jPopupFilterPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_jPopupFilterPopupMenuWillBecomeVisible
        //Set enabled for menu elements witch moving filter
        miFilterUp.setEnabled(jFilterTable.getSelectedRow() != 0
                              && jFilterTable.getRowCount() > 0);
        miFilterDown.setEnabled(jFilterTable.getSelectedRow() != jFilterTable.getRowCount() - 1
                                && jFilterTable.getRowCount() > 0);
        //Set enabled for filter
        BackupTask selectedTask = getSelectedTask();
        if (selectedTask != null)
        {
            Filter selectedFilter = selectedTask.getFilters().get(jFilterTable.getSelectedRow());
            miEditFilter.setEnabled(selectedFilter != null && selectedFilter.hasConfigForm());
        }
    }//GEN-LAST:event_jPopupFilterPopupMenuWillBecomeVisible

    private void jbAddStorageClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbAddStorageClicked
//        if (StorageList.getFactoryMap().size() == 1)
//        {
//            Factory<? extends Storage> storageFactory = (Factory<? extends Storage>) StorageList.getFactoryMap().values().toArray()[0];
//            Storage storage = storageFactory.newObject();
//            this.getSelectedTask().getStorages().add(storage);
//            this.getStorageTable().updateUI();
//        }
//        else
            jStorageMenu.show(jbAddStorage, 0, jbAddStorage.getHeight());
    }//GEN-LAST:event_jbAddStorageClicked

    private void jbDelStorageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbDelStorageActionPerformed
        BackupTask task = getSelectedTask();
        if (task != null)
        {
            int iSelectStorage = jStorageTable.getSelectedRow();
            if (iSelectStorage != -1)
            {
                task.getStorages().remove(iSelectStorage);
                task.setChanged(true);
                jStorageTable.updateUI();
            }
            else
            {
                JOptionPane.showMessageDialog(this, "Не выбрано ни одного хранилища.", "Ошибка", JOptionPane.WARNING_MESSAGE);
            }
        }
        else
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи.", "Ошибка", JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_jbDelStorageActionPerformed

    private void miAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miAboutActionPerformed
        JDialog dialogAbout = new RegBackupAboutBox(this);
        dialogAbout.setLocationRelativeTo(this);
        dialogAbout.setVisible(true);
    }//GEN-LAST:event_miAboutActionPerformed

    private void jTaskMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_jTaskMenuPopupMenuWillBecomeVisible
        miTaskUp.setEnabled(jTaskList.getSelectedIndex() != 0);
        miTaskDown.setEnabled(jTaskList.getSelectedIndex() != Tasks.getSize() - 1);
    }//GEN-LAST:event_jTaskMenuPopupMenuWillBecomeVisible

    private void addTask(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addTask
        BackupTask newTask = new BackupTask();
        Tasks.add(newTask);
        jTaskList.setSelectedIndex(0);
        jTabPanes.setSelectedIndex(1);
        jTaskName.requestFocus();
        jTaskName.selectAll();
    }//GEN-LAST:event_addTask

    private void delTask(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delTask
        int selectedIndex = jTaskList.getSelectedIndex();
        if (selectedIndex != -1)
        {
            Tasks.remove(selectedIndex);
            if (!Tasks.isEmpty())
                jTaskList.setSelectedIndex(selectedIndex);
            saveTaskList();
            jTaskList.updateUI();
        }
    }//GEN-LAST:event_delTask

    private void jbRestoreRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbRestoreRunActionPerformed
        BackupTask task = getSelectedTask();
        if (task != null)
            task.restore(this, jProgressBar, jTextLog);
    }//GEN-LAST:event_jbRestoreRunActionPerformed

    private void jPanelConfigHidden(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_jPanelConfigHidden
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            //JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи.", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (task.isChanged())
            if (JOptionPane.showConfirmDialog(this, "Созранить изменения настроек задачи", "Вопрос", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
            {
                saveTaskList();
                task.setChanged(false);
            }
    }//GEN-LAST:event_jPanelConfigHidden

    private void jShowFileListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jShowFileListActionPerformed
        FileListForm flf = null;
        try {
            flf = new FileListForm(getSelectedTask().getFileList(), false, "Список файлов предназначенных для архивации", "Список файлов");
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "Ошибка", JOptionPane.ERROR_MESSAGE);
            Logger.getLogger(RegBackupMainForm.class.getName()).log(Level.SEVERE, null, ex);
            return;
        }
        flf.setVisible(true);
    }//GEN-LAST:event_jShowFileListActionPerformed

    private void jRuleTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jRuleTableKeyPressed
        if (getSelectedTask() != null)
        {
            jbEditRule.setEnabled(true);
            jbDelRule.setEnabled(true);
        }
    }//GEN-LAST:event_jRuleTableKeyPressed

    private void jbSaveTaskClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbSaveTaskClicked
        BackupTask selectedTask = getSelectedTask();
        if (selectedTask == null)
        {
            JOptionPane.showConfirmDialog(this, "Невыбрано ниодного задания!", "Внимание!", JOptionPane.WARNING_MESSAGE);
            return;
        }
        saveTaskList();
    }//GEN-LAST:event_jbSaveTaskClicked

    private void jbUndoTaskChangesClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbUndoTaskChangesClicked
        int iSelectedTask = jTaskList.getSelectedIndex();
        int iSelectedPage = jTabPanes.getSelectedIndex();
        loadTaskList();
        jTaskList.setSelectedIndex(iSelectedTask);
        jTabPanes.setSelectedIndex(iSelectedPage);
    }//GEN-LAST:event_jbUndoTaskChangesClicked

    private void jStorageMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_jStorageMenuPopupMenuWillBecomeVisible

    }//GEN-LAST:event_jStorageMenuPopupMenuWillBecomeVisible

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new RegBackupMainForm().setVisible(true);
            }
        });
    }

    @Action
    public void addRule() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "ERROR", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (task.getRules().add(new Rule()))
            task.setChanged(true);
        jRuleTable.updateUI();
    }

    @Action
    public void editRule() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "ERROR", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (task.getRules().get(jRuleTable.getSelectedRow()).showConfigForm(this))
            task.setChanged(true);
        jRuleTable.updateUI();
    }

    @Action
    public void delRule() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "ERROR", JOptionPane.ERROR_MESSAGE);
            return;
        }
        int iRow = jRuleTable.getSelectedRow();
        if (iRow == -1)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано правило для удаления", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (task.getRules().remove(iRow) != null)
        {
            task.setChanged(true);
        }
        if (getSelectedTask() == null)
        {
            jbEditRule.setEnabled(false);
            jbDelRule.setEnabled(false);
        }
        jRuleTable.updateUI();
    }

    @Action
    public void loadTask() throws FileNotFoundException {
        JFileChooser jOpenDialog = new JFileChooser();
        jOpenDialog.setFileFilter(new ExtensionFileFilter("Файлы задач RegBackup (*.rbt.xml)", "rbt.xml"));
        if (jOpenDialog.showOpenDialog(this) == JFileChooser.APPROVE_OPTION)
        {
            XStream serializer = new XStream(new DomDriver());
            Annotations.configureAliases(serializer, BackupTask.class);
            Annotations.configureAliases(serializer, Rule.class);
            FileInputStream fis = new FileInputStream(jOpenDialog.getSelectedFile().getPath());
            Tasks.add((BackupTask) serializer.fromXML(fis));
        }
    }

    @Action
    public void saveTask() throws FileNotFoundException {
        if (getSelectedTask() == null)
        {
            jStatus.setText("No task selected.");
            return;
        }
        JFileChooser jSaveDialog = new JFileChooser();
        jSaveDialog.setFileFilter(new ExtensionFileFilter("Файлы задач RegBackup (*.rbt.xml)", "rbt.xml"));
        if (jSaveDialog.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
        {
            String FileName = jSaveDialog.getSelectedFile().getPath();
            if (!FileName.endsWith(".rbt.xml"))
                FileName += ".rbt.xml";
            XStream serializer = new XStream();
            Annotations.configureAliases(serializer, BackupTask.class);
            Annotations.configureAliases(serializer, Rule.class);
            for (Factory<? extends Filter> ff : FilterList.getFactoryMap().values())
                Annotations.configureAliases(serializer, ff.getGeneratedClass());
            FileOutputStream fos = new FileOutputStream(FileName);
            serializer.toXML(getSelectedTask(), fos);
        }
        else
            jStatus.setText("Пользователь отменил сохранение.");
    }


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPopupMenu.Separator jExitSeparator;
    private javax.swing.JPopupMenu jFilterMenu;
    private javax.swing.JTable jFilterTable;
    private javax.swing.JLabel jFilterTableLabel;
    private javax.swing.JLabel jLastRun;
    private javax.swing.JLabel jLastRunLabel;
    private javax.swing.JPanel jPanelConfig;
    private javax.swing.JPanel jPanelMain;
    private javax.swing.JPopupMenu jPopupFilter;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JTable jRuleTable;
    private javax.swing.JLabel jRuleTableLabel;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JSeparator jSeparator3;
    private javax.swing.JSeparator jSeparator4;
    private javax.swing.JButton jShowFileList;
    private javax.swing.JLabel jStatus;
    private javax.swing.JLabel jStatusLabel;
    private javax.swing.JPopupMenu jStorageMenu;
    private javax.swing.JTable jStorageTable;
    private javax.swing.JLabel jStorageTableLabel;
    private javax.swing.JTabbedPane jTabPanes;
    private javax.swing.JList jTaskList;
    private javax.swing.JPopupMenu jTaskMenu;
    private javax.swing.JTextField jTaskName;
    private javax.swing.JLabel jTaskNameLabel;
    private javax.swing.JTextArea jTextLog;
    private javax.swing.JButton jbAddFilter;
    private javax.swing.JButton jbAddRule;
    private javax.swing.JButton jbAddStorage;
    private javax.swing.JButton jbAddTask;
    private javax.swing.JButton jbBackupRun;
    private javax.swing.JButton jbDelFilter;
    private javax.swing.JButton jbDelRule;
    private javax.swing.JButton jbDelStorage;
    private javax.swing.JButton jbEditFilter;
    private javax.swing.JButton jbEditRule;
    private javax.swing.JButton jbEditStorage;
    private javax.swing.JButton jbRestoreRun;
    private javax.swing.JButton jbSaveTask;
    private javax.swing.JButton jbUndoTaskChanges;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem miDelFilter;
    private javax.swing.JMenuItem miEditFilter;
    private javax.swing.JMenuItem miFilterDown;
    private javax.swing.JMenuItem miFilterUp;
    private javax.swing.JMenuItem miHelp;
    private javax.swing.JMenuItem miLoadTask;
    private javax.swing.JMenuItem miSaveTask;
    private javax.swing.JMenuItem miTaskAdd;
    private javax.swing.JMenuItem miTaskDel;
    private javax.swing.JMenuItem miTaskDown;
    private javax.swing.JMenuItem miTaskUp;
    // End of variables declaration//GEN-END:variables

    Application app = null;
    ListModel<BackupTask> Tasks = new ListModel<BackupTask>();

    XStream taskListSerializer = null;

    public XStream getTaskListSerializer() {
        if (taskListSerializer == null)
        {
            taskListSerializer = new XStream(new DomDriver());
            taskListSerializer.alias("tasks", Tasks.getClass());
            Annotations.configureAliases(taskListSerializer, BackupTask.class);
            Annotations.configureAliases(taskListSerializer, Rule.class);
            for (Factory<? extends Filter> ff : FilterList.getFactoryMap().values())
                Annotations.configureAliases(taskListSerializer, ff.getGeneratedClass());
        }
        return taskListSerializer;
    }

    private void saveTaskList() {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("tasks.xml");
        } catch (FileNotFoundException exc) {
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), "Ошибка", JOptionPane.WARNING_MESSAGE);
        }
        if (fos != null)
            getTaskListSerializer().toXML(Tasks, fos);
    }

    private void loadTaskList() {
        FileInputStream fis = null;
        try {
             fis = new FileInputStream("tasks.xml");
        } catch (FileNotFoundException exc) {
            Tasks = new ListModel<BackupTask>();
            jTaskList.setModel(Tasks);
            jTaskList.updateUI();
            addTask(null);            
        }
        if (fis != null)
        {
            Tasks = (ListModel<BackupTask>) getTaskListSerializer().fromXML(fis);
            jTaskList.setModel(Tasks);
            jTaskList.updateUI();
        }
    }


    @Action
    public void editFilter() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        int SelectedRow = jFilterTable.getSelectedRow();
        if (SelectedRow == -1)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ниодного фильтра", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        Filter filter = task.getFilters().get(SelectedRow);
        if (filter.hasConfigForm())
            if (filter.showConfigForm(this))
                task.setChanged(true);
        else
            JOptionPane.showMessageDialog(this, "Данный фильтр не имеет формы настроек", "Ошибка", JOptionPane.ERROR_MESSAGE);
    }

    @Action
    public void delFilter() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        int SelectedRow = jFilterTable.getSelectedRow();
        if (SelectedRow == -1)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ниодного фильтра", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        task.getFilters().remove(SelectedRow);
        task.setChanged(true);
        jFilterTable.updateUI();
    }

    @Action
    public void moveUpFilter() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        int row = jFilterTable.getSelectedRow();
        if (row == -1)
            JOptionPane.showMessageDialog(this, "Не выбрано ниодного фильтра", "Ошибка", JOptionPane.ERROR_MESSAGE);
        else
        {
            Filter f = task.getFilters().remove(row);
            task.getFilters().add(row - 1, f);
            task.setChanged(true);
            jFilterTable.updateUI();
        }
    }

    @Action
    public void moveDownFilter() {
        BackupTask task = getSelectedTask();
        if (task == null)
        {
            JOptionPane.showMessageDialog(this, "Не выбрано ни одной задачи", "Ошибка", JOptionPane.ERROR_MESSAGE);
            return;
        }
        int row = jFilterTable.getSelectedRow();
        if (row == -1)
            JOptionPane.showMessageDialog(this, "Не выбрано ниодного фильтра", "Ошибка", JOptionPane.ERROR_MESSAGE);
        else
        {
            Filter f = task.getFilters().remove(row);
            task.getFilters().add(row + 1, f);
            task.setChanged(true);
            jFilterTable.updateUI();
        }
    }


    }
